import http from 'http';
import https from 'https';
import net from 'net';
import tls from 'tls';
import url from 'url';
import { createHttpRequest, createHttpResponse, createHttpTransaction, generateId } from '../types/index.js';

// 导入重构后的模块
import { CertManager } from './cert-manager.js';
import { ConnectionManager } from './connection-manager.js';
import { HttpHandler } from './http-handler.js';
import { ProxyUtils } from './utils.js';

/**
 * 重构后的代理服务器
 * 采用模块化设计，职责分离
 */
export class ProxyServer {
  constructor(config, database, ruleEngine, webSocketServer) {
    this.config = config;
    this.database = database;
    this.ruleEngine = ruleEngine;
    this.webSocketServer = webSocketServer;
    
    // 服务器实例
    this.httpServer = null;
    this.httpsServer = null;
    this.isRunning = false;
    
    // 模块化组件
    this.certManager = new CertManager();
    this.connectionManager = new ConnectionManager();
    this.httpHandler = new HttpHandler(database, ruleEngine, webSocketServer, this.connectionManager);
  }

  /**
   * 启动代理服务器
   */
  async start() {
    if (this.isRunning) {
      console.log('🔄 代理服务器已在运行');
      return;
    }

    try {
      // 生成根证书
      await this.certManager.generateRootCert();
      
      // 启动HTTP代理服务器
      await this.startHttpProxy();
      
      // 启动HTTPS代理服务器
      if (this.config.interceptHttps) {
        await this.startHttpsProxy();
      }
      
      this.isRunning = true;
      console.log(`🌐 HTTP代理服务器启动: 0.0.0.0:${this.config.port} (可通过 localhost:${this.config.port} 访问)`);
      if (this.config.interceptHttps) {
        console.log(`🔒 HTTPS代理服务器启动: 0.0.0.0:${this.config.httpsPort} (可通过 localhost:${this.config.httpsPort} 访问)`);
      }
      
    } catch (error) {
      console.error('❌ 启动代理服务器失败:', error);
      throw error;
    }
  }

  /**
   * 停止代理服务器
   */
  async stop() {
    try {
      console.log('🛑 正在停止代理服务器...');
      
      // 先强制关闭所有活跃连接
      await this.connectionManager.forceCloseAllConnections();
      
      const closePromises = [];
      
      // 停止HTTP服务器
      if (this.httpServer) {
        console.log('🛑 正在停止HTTP代理服务器...');
        closePromises.push(new Promise((resolve, reject) => {
          this.httpServer.close((error) => {
            if (error) {
              console.error('❌ 停止HTTP服务器失败:', error);
              reject(error);
            } else {
              console.log('✅ HTTP代理服务器已停止');
              resolve();
            }
          });
        }));
        this.httpServer = null;
      }

      // 停止HTTPS服务器
      if (this.httpsServer) {
        console.log('🛑 正在停止HTTPS代理服务器...');
        closePromises.push(new Promise((resolve, reject) => {
          this.httpsServer.close((error) => {
            if (error) {
              console.error('❌ 停止HTTPS服务器失败:', error);
              reject(error);
            } else {
              console.log('✅ HTTPS代理服务器已停止');
              resolve();
            }
          });
        }));
        this.httpsServer = null;
      }

      // 等待所有服务器停止
      if (closePromises.length > 0) {
        await Promise.all(closePromises);
      }

      // 清理资源
      this.certManager.clearCache();
      this.connectionManager.clearAll();
      
      this.isRunning = false;
      console.log('✅ 代理服务器已完全停止');
      
    } catch (error) {
      console.error('❌ 停止代理服务器失败:', error);
      this.isRunning = false;
      throw error;
    }
  }

  /**
   * 启动HTTP代理服务器
   */
  async startHttpProxy() {
    return new Promise((resolve, reject) => {
      this.httpServer = http.createServer();
      
      // 处理普通HTTP请求
      this.httpServer.on('request', (req, res) => {
        this.connectionManager.addHttpConnection(req.socket);
        this.httpHandler.handleHttpRequest(req, res);
      });
      
      // 处理HTTPS CONNECT请求
      this.httpServer.on('connect', (req, clientSocket, head) => {
        this.connectionManager.addHttpConnection(clientSocket);
        this.handleHttpsConnect(req, clientSocket, head);
      });
      
      this.httpServer.on('error', (error) => {
        console.error('❌ HTTP代理服务器错误:', error);
        reject(error);
      });
      
      this.httpServer.listen(this.config.port, '0.0.0.0', () => {
        resolve();
      });
    });
  }

  /**
   * 启动HTTPS代理服务器
   */
  async startHttpsProxy() {
    return new Promise((resolve, reject) => {
      this.httpsServer = https.createServer({
        key: this.certManager.rootKey,
        cert: this.certManager.rootCert,
        SNICallback: this.certManager.getSNICertCallback()
      });
      
      this.httpsServer.on('request', (req, res) => {
        this.connectionManager.addHttpsConnection(req.socket);
        this.handleHttpsRequest(req, res);
      });
      
      this.httpsServer.on('error', (error) => {
        console.error('❌ HTTPS代理服务器错误:', error);
        reject(error);
      });
      
      this.httpsServer.listen(this.config.httpsPort, '0.0.0.0', () => {
        resolve();
      });
    });
  }

  /**
   * 处理HTTPS CONNECT请求
   */
  handleHttpsConnect(req, clientSocket, head) {
    const targetUrl = new URL(`http://${req.url}`);
    const targetHost = targetUrl.hostname;
    const targetPort = targetUrl.port || 443;

    console.log(`🔗 CONNECT请求: ${targetHost}:${targetPort}`);

    if (this.config.interceptHttps) {
      console.log(`🔓 启用HTTPS拦截模式: ${targetHost}`);
      this.createInterceptedTunnel(req, clientSocket, head, targetHost, targetPort);
    } else {
      console.log(`🚇 创建透明隧道: ${targetHost}:${targetPort}`);
      this.createTransparentTunnel(req, clientSocket, head, targetUrl);
    }
  }

  /**
   * 创建拦截隧道（MITM）
   */
  async createInterceptedTunnel(req, clientSocket, head, targetHost, targetPort) {
    try {
      // 确保有证书
      const certData = await this.certManager.ensureCertForHost(targetHost);

      // 发送连接成功响应
      clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');

      // 创建到客户端的TLS连接（使用我们的假证书）
      const tlsSocket = new tls.TLSSocket(clientSocket, {
        isServer: true,
        key: certData.key,
        cert: certData.cert,
        requestCert: false,
        rejectUnauthorized: false
      });

      this.connectionManager.addHttpsConnection(tlsSocket);

      console.log(`✅ 客户端TLS连接已建立: ${targetHost}`);
      
      // 获取客户端协议版本和TLS版本
      let clientHttpVersion = 'HTTP/1.1'; // 客户端HTTP版本（默认）
      let clientTlsVersion = 'TLS/1.2'; // 客户端TLS版本（默认）
      
      // 获取客户端TLS版本
      tlsSocket.once('secure', () => {
        const tlsVersion = tlsSocket.getProtocol();
        if (tlsVersion) {
          clientTlsVersion = tlsVersion.toUpperCase().replace('V', '/');
          console.log(`🔒 客户端TLS版本: ${clientTlsVersion}`);
        }
      });
      
      // 用于累积HTTP请求数据
      let requestBuffer = Buffer.alloc(0);
      let isFirstRequest = true;
      
      // 处理来自客户端的HTTPS数据
      tlsSocket.on('data', async (data) => {
        try {
          // 累积数据到缓冲区
          requestBuffer = Buffer.concat([requestBuffer, data]);
          
          // 尝试解析完整的HTTP请求
          while (requestBuffer.length > 0) {
            const requestStr = requestBuffer.toString('utf8');
            
            // 查找HTTP请求的结束标志
            const headerEndIndex = requestStr.indexOf('\r\n\r\n');
            if (headerEndIndex === -1) {
              // 请求头还不完整，继续等待数据
              break;
            }
            
            // 提取请求头部分
            const headerStr = requestStr.substring(0, headerEndIndex);
            const lines = headerStr.split('\r\n');
            
            if (lines.length === 0) {
              // 清除无效数据
              requestBuffer = requestBuffer.slice(1);
              continue;
            }
            
            const requestLine = lines[0];
            const requestLineParts = requestLine.split(' ');
            
            // 验证HTTP请求行格式
            if (requestLineParts.length !== 3) {
              console.log(`⚠️ 跳过无效请求行: ${requestLine.substring(0, 50)}...`);
              requestBuffer = requestBuffer.slice(headerEndIndex + 4);
              continue;
            }
            
            const [method, path, httpVersion] = requestLineParts;
            
            // 从HTTP请求行获取客户端HTTP版本
            if (httpVersion && httpVersion.startsWith('HTTP/')) {
              clientHttpVersion = httpVersion;
            }
            
            // 验证HTTP方法
            if (!ProxyUtils.isValidHttpMethod(method)) {
              console.log(`⚠️ 跳过无效HTTP方法: ${method}`);
              requestBuffer = requestBuffer.slice(headerEndIndex + 4);
              continue;
            }
            
            // 验证路径
            if (!ProxyUtils.isValidPath(path)) {
              console.log(`⚠️ 跳过无效路径: ${path}`);
              requestBuffer = requestBuffer.slice(headerEndIndex + 4);
              continue;
            }
            
            // 构建完整URL
            const fullUrl = `https://${targetHost}${path}`;
            console.log(`🔒 HTTPS请求: ${method} ${fullUrl}`);
            
            // 解析请求头
            const headers = {};
            let contentLength = 0;
            
            for (let i = 1; i < lines.length; i++) {
              const colonIndex = lines[i].indexOf(': ');
              if (colonIndex > 0) {
                const key = lines[i].substring(0, colonIndex).toLowerCase();
                const value = lines[i].substring(colonIndex + 2);
                headers[key] = value;
                
                if (key === 'content-length') {
                  contentLength = parseInt(value) || 0;
                }
              }
            }
            
            // 计算已接收的请求数据长度
            const headerLength = headerEndIndex + 4;
            const bodyReceived = requestBuffer.length - headerLength;
            
            // 检查是否已接收完整的请求体
            if (contentLength > 0 && bodyReceived < contentLength) {
              // 请求体还不完整，继续等待数据
              break;
            }
            
            // 提取请求体
            let body = null;
            let bodyBuffer = null;
            if (contentLength > 0) {
              bodyBuffer = requestBuffer.slice(headerLength, headerLength + contentLength);
              
              // 检查Content-Type来决定如何处理请求体
              const contentType = headers['content-type'] || '';
              if (ProxyUtils.isTextContent(contentType)) {
                // 文本类型的请求体，转换为字符串
                body = bodyBuffer.toString('utf8');
              } else {
                // 二进制数据，保持Buffer格式用于转发
                body = `[Binary data: ${bodyBuffer.length} bytes]`;
              }
            }
            
            // 移除已处理的请求数据
            const requestTotalLength = headerLength + contentLength;
            requestBuffer = requestBuffer.slice(requestTotalLength);
            
            // 处理HTTPS请求
            await this.processHttpsRequest({
              method,
              path,
              fullUrl,
              headers: ProxyUtils.cleanProxyHeaders(headers),
              body,
              bodyBuffer,
              targetHost,
              targetPort,
              tlsSocket,
              clientHttpVersion,
              clientTlsVersion
            });
          }
          
        } catch (error) {
          console.error(`❌ 处理HTTPS数据失败 (${targetHost}):`, error.message);
        }
      });

      tlsSocket.on('error', (error) => {
        console.error(`❌ 客户端TLS连接错误 (${targetHost}):`, error.message);
      });

      tlsSocket.on('close', () => {
        console.log(`🔒 客户端TLS连接关闭: ${targetHost}`);
      });

    } catch (error) {
      console.error(`❌ 创建拦截隧道失败 (${targetHost}):`, error.message);
      try {
        clientSocket.write('HTTP/1.1 500 Internal Server Error\r\n\r\n');
        clientSocket.end();
      } catch (writeError) {
        console.error(`❌ 发送错误响应失败:`, writeError.message);
      }
    }
  }

  /**
   * 处理HTTPS请求
   */
  async processHttpsRequest({ method, path, fullUrl, headers, body, bodyBuffer, targetHost, targetPort, tlsSocket, clientHttpVersion, clientTlsVersion }) {
    const requestStartTime = Date.now();
    const transactionId = generateId();
    
    // 用于记录远程服务器的协议版本
    let remoteHttpVersion = 'HTTP/1.1';
    let remoteTlsVersion = 'TLS/1.2';

    try {
      // 创建到真实服务器的HTTPS连接
      const options = {
        hostname: targetHost,
        port: parseInt(targetPort) || 443,
        path: path,
        method: method,
        headers: {
          ...headers,
          // 确保Host头正确
          'host': targetHost,
        },
        rejectUnauthorized: false
      };

      console.log(`🔄 转发请求到: ${targetHost}${path}`);
      console.log(`📋 请求头数量: ${Object.keys(headers).length}`);
      if (body) {
        console.log(`📦 请求体大小: ${body.length} bytes`);
      }

      const proxyReq = https.request(options, (proxyRes) => {
        console.log(`✅ 收到响应: ${proxyRes.statusCode} ${proxyRes.statusMessage}`);
        
        // 简单的远程服务器TLS版本检测
        if (proxyReq.socket && proxyReq.socket.getProtocol) {
          const tlsProtocol = proxyReq.socket.getProtocol();
          if (tlsProtocol) {
            remoteTlsVersion = tlsProtocol.toUpperCase().replace('V', '/');
            console.log(`🔐 远程服务器TLS版本: ${remoteTlsVersion}`);
          }
        }
        
        // 构建HTTP响应给客户端
        const responseHeader = ProxyUtils.buildHttpResponseHeader(proxyRes.statusCode, proxyRes.statusMessage, proxyRes.headers);
        
        // 发送响应头到客户端
        try {
          tlsSocket.write(responseHeader);
        } catch (error) {
          console.error(`❌ 发送响应头失败:`, error.message);
          return;
        }
        
        let responseBody = '';
        let responseBodyBuffer = Buffer.alloc(0);
        
        // 转发响应体
        proxyRes.on('data', (chunk) => {
          responseBodyBuffer = Buffer.concat([responseBodyBuffer, chunk]);
          try {
            tlsSocket.write(chunk);
          } catch (error) {
            console.error(`❌ 转发响应数据失败:`, error.message);
          }
        });
        
        proxyRes.on('end', async () => {
          const endTime = Date.now();
          console.log(`🏁 响应传输完成: ${responseBodyBuffer.length} bytes`);
          
          // 解压响应内容
          const contentEncoding = proxyRes.headers['content-encoding'];
          const contentType = proxyRes.headers['content-type'] || '';
          
          try {
            if (ProxyUtils.isTextContent(contentType)) {
              // 文本内容，尝试解压
              responseBody = await ProxyUtils.decompressResponseBody(responseBodyBuffer, contentEncoding);
            } else {
              responseBody = `[Binary data: ${responseBodyBuffer.length} bytes]`;
            }
          } catch (error) {
            console.warn('⚠️ 处理响应体失败:', error.message);
            responseBody = `[Binary data: ${responseBodyBuffer.length} bytes]`;
          }
          
          // 记录完整的事务
          const duration = endTime - requestStartTime;
          
          console.log(`📝 记录事务时使用的协议版本:`);
          console.log(`   🖥️  客户端: ${clientHttpVersion} (${clientTlsVersion})`);
          console.log(`   🌐 远程服务器: ${remoteHttpVersion} (${remoteTlsVersion})`);
          
          const httpRequest = createHttpRequest({
            id: transactionId,
            url: fullUrl,
            method: method,
            headers: headers,
            cookies: ProxyUtils.extractCookies(headers),
            body: body,
            timestamp: requestStartTime,
            clientHttpVersion: clientHttpVersion, // 客户端HTTP版本
            remoteHttpVersion: remoteHttpVersion, // 远程服务器HTTP版本
            tlsVersion: clientTlsVersion, // 客户端TLS版本
            clientIp: tlsSocket.remoteAddress,
            remoteIp: targetHost
          });

          const httpResponse = createHttpResponse({
            id: `${transactionId}-response`,
            requestId: transactionId,
            statusCode: proxyRes.statusCode,
            headers: proxyRes.headers,
            cookies: ProxyUtils.extractCookies(proxyRes.headers),
            body: responseBody,
            bodySize: responseBodyBuffer.length,
            timestamp: endTime,
            remoteHttpVersion: remoteHttpVersion, // 远程服务器HTTP版本
            tlsVersion: remoteTlsVersion // 远程服务器TLS版本
          });

          const transaction = createHttpTransaction({
            id: transactionId,
            request: httpRequest,
            response: httpResponse,
            duration,
            createdAt: requestStartTime
          });

          // 保存到数据库
          this.database.saveTransaction(transaction);

          // 通过WebSocket实时推送
          if (this.webSocketServer) {
            this.webSocketServer.broadcastTransaction(transaction);
          }

          // 执行规则匹配
          if (this.ruleEngine) {
            this.ruleEngine.processTransaction(transaction);
          }
          
          console.log(`📡 广播事务: ${method} ${fullUrl}`);
        });
        
        proxyRes.on('error', (error) => {
          console.error(`❌ 接收响应失败:`, error.message);
        });
      });

      proxyReq.on('error', (error) => {
        console.error(`❌ HTTPS代理请求失败 (${targetHost}):`, error.message);
        try {
          const errorResponse = ProxyUtils.createErrorResponse(502, 'Bad Gateway');
          tlsSocket.write(errorResponse);
        } catch (writeError) {
          console.error(`❌ 发送错误响应失败:`, writeError.message);
        }
      });

      // 发送请求体（如果有）
      if (bodyBuffer && bodyBuffer.length > 0) {
        console.log(`📤 发送请求体: ${bodyBuffer.length} bytes`);
        proxyReq.write(bodyBuffer);
      }
      
      console.log(`🚀 发送请求到目标服务器`);
      proxyReq.end();

    } catch (error) {
      console.error(`❌ 处理HTTPS请求失败 (${targetHost}):`, error.message);
    }
  }

  /**
   * 创建透明隧道
   */
  createTransparentTunnel(req, clientSocket, head, targetUrl) {
    const targetHost = targetUrl.hostname;
    const targetPort = targetUrl.port || 443;

    const serverSocket = net.connect(targetPort, targetHost, () => {
      clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
      serverSocket.write(head);
      serverSocket.pipe(clientSocket);
      clientSocket.pipe(serverSocket);
    });

    serverSocket.on('error', (error) => {
      console.error(`❌ 目标服务器连接失败 (${targetHost}:${targetPort}):`, error.message);
      clientSocket.end();
    });

    clientSocket.on('error', (error) => {
      console.error(`❌ 客户端连接错误:`, error.message);
      serverSocket.end();
    });
  }

  /**
   * 处理HTTPS请求（用于直接HTTPS服务器）
   */
  async handleHttpsRequest(req, res) {
    const startTime = Date.now();
    const transactionId = generateId();

    try {
      const fullUrl = `https://${req.headers.host}${req.url}`;
      console.log(`🔐 HTTPS请求: ${req.method} ${fullUrl}`);

      // 跳过系统测试请求
      if (this.connectionManager.isSystemTestRequest(fullUrl)) {
        console.log(`⚠️ 跳过系统测试请求: ${fullUrl}`);
        res.writeHead(204);
        res.end();
        return;
      }

      // 使用HTTP处理器处理请求
      await this.httpHandler.handleHttpRequest(req, res);

    } catch (error) {
      console.error(`❌ 处理HTTPS请求失败:`, error.message);
      if (!res.headersSent) {
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('内部服务器错误');
      }
    }
  }

  /**
   * 获取代理服务器状态
   */
  getStatus() {
    return {
      isRunning: this.isRunning,
      httpPort: this.config.port,
      httpsPort: this.config.httpsPort,
      interceptHttps: this.config.interceptHttps,
      connections: this.connectionManager.getStats(),
      certificates: this.certManager.getStats()
    };
  }

  /**
   * 同步停止（用于紧急情况）
   */
  stopSync() {
    try {
      this.connectionManager.forceCloseAllConnectionsSync();
      
      if (this.httpServer) {
        this.httpServer.close();
        this.httpServer = null;
      }
      
      if (this.httpsServer) {
        this.httpsServer.close();
        this.httpsServer = null;
      }
      
      this.certManager.clearCache();
      this.connectionManager.clearAll();
      this.isRunning = false;
      
    } catch (error) {
      console.error('❌ 同步停止代理服务器失败:', error.message);
    }
  }

  /**
   * 强制关闭所有连接（同步）
   */
  forceCloseAllConnectionsSync() {
    this.connectionManager.forceCloseAllConnectionsSync();
  }
} 